package com.hq.ims.data.service;

import com.hq.ims.data.dao.CompanyEmployeeMapper;
import com.hq.ims.data.entity.*;
import com.hq.ims.data.utils.ErrMsgConstant;
import com.hq.ims.data.utils.LocalConstant;
import com.hq.ims.data.vo.CompanyEmployeeMapstruct;
import com.hq.ims.data.vo.PermissionRoleMapstruct;
import com.hq.ims.data.vo.UserMapstruct;
import com.hq.mybatis.base.BaseService;
import com.hq.mybatis.base.page.RequestPage;
import com.hq.utils.util.ListUtils;
import com.hq.utils.util.ObjectUtils;
import lombok.NonNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * jiang bai ping
 *
 * @Email 526666031@qq.com
 * @Detail 公司人员表服务实现类
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class BaseCompanyEmployeeService extends BaseService<CompanyEmployeeMapper, CompanyEmployee> {

    @Resource
    private BaseCompanyDepartmentService baseCompanyDepartmentService;
    @Resource
    private BaseCompanyService baseCompanyService;
    @Resource
    private BaseUserService baseUserService;
    @Resource
    private BasePermissionMapAuthorityUserService basePermissionMapGroupUserService;
    @Resource
    private BasePermissionMapAuthorityUserService basePermissionMapAuthorityUserService;
    @Resource
    private BasePermissionMapRoleUserService basePermissionMapRoleUserService;
    @Resource
    private BaseCompanyDepartmentEmployeeService baseCompanyMapDepartmentUserService;
    @Resource
    private BaseCompanyDepartmentEmployeeService baseCompanyDepartmentEmployeeService;
    @Resource
    private BasePermissionRoleService basePermissionRoleService;

    /**
     * 添加用户
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean addData(
            @NonNull String companyId,
            @NonNull String userId,
            @NonNull Boolean isPartTimeJob
    ) {
        //用户ID去重
        //判断用户是否已加入公司
        if (!this.userIsJoinCompany(userId, companyId, isPartTimeJob)) {
            Company company = baseCompanyService.getById(companyId);
            ObjectUtils.isNullThrow(companyId, ErrMsgConstant.COMPANY_INFO_NOT_EXISTS);
            //完成用户和公司的绑定
            CompanyEmployee companyEmployee = new CompanyEmployee();
            companyEmployee.setIsPartTimeJob(isPartTimeJob);
            companyEmployee.setCompanyId(companyId);
            companyEmployee.setCompanyName(company.getCompanyName());
            companyEmployee.setUserId(userId);
            companyEmployee.setIsAdmin(false);
            companyEmployee.setIsResign(false);
            companyEmployee.insert();
        }
        return true;
    }

    /**
     * 判断公司是否已存在该未离职用户
     *
     * @param userId    用户id
     * @param companyId 公司标识
     */
    public boolean userIsJoinCompany(
            @NonNull String userId,
            @NonNull String companyId,
            Boolean isPartTimeJob
    ) {
        return this.lambdaQuery()
                .eq(CompanyEmployee::getUserId, userId)
                .eq(CompanyEmployee::getCompanyId, companyId)
                .eq(CompanyEmployee::getIsResign, false)
                .eq(isPartTimeJob != null, CompanyEmployee::getIsPartTimeJob, isPartTimeJob)
                .count() > 0;
    }

    /**
     * 获取加入公司的员工数量
     *
     * @param companyId 公司ID
     */
    public Long getCompanyEmployeeCountByCompanyId(
            @NonNull String companyId,
            Boolean isPartTimeJob
    ) {
        return this.lambdaQuery()
                .eq(CompanyEmployee::getCompanyId, companyId)
                .eq(CompanyEmployee::getIsResign, false)
                .eq(isPartTimeJob != null, CompanyEmployee::getIsPartTimeJob, isPartTimeJob)
                .count();
    }


    /**
     * 获取员工信息根据用户id和公司id
     */
    public List<CompanyEmployee> getByUserIdAndCompanyId(
            @NonNull String userId,
            @NonNull String companyId,
            Boolean isPartTimeJob
    ) {
        List<CompanyEmployee> companyEmployeeList = this.lambdaQuery()
                .eq(CompanyEmployee::getUserId, userId)
                .eq(CompanyEmployee::getCompanyId, companyId)
                .eq(CompanyEmployee::getIsResign, false)
                .eq(isPartTimeJob != null, CompanyEmployee::getIsPartTimeJob, isPartTimeJob)
                .orderByDesc(CompanyEmployee::getCreateDateTime)
                .list();
        return companyEmployeeList;
    }

    public List<CompanyEmployee> getByUserId(
            @NonNull String userId,
            Boolean isPartTimeJob
    ) {
        return this.lambdaQuery()
                .eq(CompanyEmployee::getUserId, userId)
                .eq(CompanyEmployee::getIsResign, false)
                .eq(isPartTimeJob != null, CompanyEmployee::getIsPartTimeJob, isPartTimeJob)
                .orderByDesc(CompanyEmployee::getCreateDateTime)
                .list();
    }

    public List<String> getUserAllCompanyIdListByUserId(
            @NonNull String userId,
            Boolean isPartTimeJob
    ) {
        List<CompanyEmployee> companyEmployeeList = this.lambdaQuery()
                .select(CompanyEmployee::getCompanyId)
                .eq(CompanyEmployee::getUserId, userId)
                .eq(CompanyEmployee::getIsResign, false)
                .eq(isPartTimeJob != null, CompanyEmployee::getIsPartTimeJob, isPartTimeJob)
                .orderByDesc(CompanyEmployee::getCreateDateTime)
                .groupBy(CompanyEmployee::getCompanyId)
                .list();

        if (ListUtils.isNotExistsEle(companyEmployeeList)) {
            return ListUtils.newEmptyList();
        }
        return companyEmployeeList.stream().map(CompanyEmployee::getCompanyId).collect(Collectors.toList());
    }

    /**
     * 获取员工信息根据用户id和公司id
     */
    public List<CompanyEmployee> getByUserIdListAndCompanyId(
            @NonNull List<String> userIdList,
            @NonNull String companyId,
            Boolean isPartTimeJob
    ) {
        if (ListUtils.isNotExistsEle(userIdList)) {
            return ListUtils.newEmptyList();
        }
        return this.lambdaQuery()
                .in(CompanyEmployee::getUserId, userIdList)
                .eq(CompanyEmployee::getCompanyId, companyId)
                .eq(isPartTimeJob != null, CompanyEmployee::getIsPartTimeJob, isPartTimeJob)
                .orderByDesc(CompanyEmployee::getCreateDateTime)
                .list();
    }


    /**
     * 设置员工离职
     *
     * @param userId    用户ID
     * @param companyId 公司ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void userQuitByUserIdAndCompanyId(
            String userId,
            String companyId
    ) {
        //设置用户离职
        this.lambdaUpdate().eq(CompanyEmployee::getUserId, userId)
                .eq(CompanyEmployee::getCompanyId, companyId)
                .set(CompanyEmployee::getIsResign, true)
                .update();
    }

    /**
     * 删除员工用户和用户相关权限
     *
     * @param userId    用户ID
     * @param companyId 公司ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void delByUserIdAndCompanyIdAndDelOtherBus(
            String userId,
            String companyId
    ) {
        //移除部门
        baseCompanyDepartmentEmployeeService.lambdaUpdate().eq(CompanyDepartmentEmployee::getUserId, userId)
                .eq(CompanyDepartmentEmployee::getCompanyId, companyId)
                .remove();
        //移除用户在该公司权限
        basePermissionMapAuthorityUserService.delByUserIdAndCompanyId(userId, companyId);
        //移除用户在该公司角色
        basePermissionMapRoleUserService.delByUserIdAndCompanyId(userId, companyId);
    }

    /**
     * 获取公司中员工中的管理员
     */
    public CompanyEmployee getCompanyAdminByCompanyId(
            @NonNull String companyId
    ) {
        CompanyEmployee companyEmployee = this.lambdaQuery()
                .eq(CompanyEmployee::getCompanyId, companyId)
                .eq(CompanyEmployee::getIsAdmin, true)
                .eq(CompanyEmployee::getIsResign, false)
                .last(LocalConstant.LIMIT_1)
                .one();

        return companyEmployee;
    }

    /***
     * 根据公司I获取
     * @param companyId 公司ID
     */
    public List<CompanyEmployee> getByCompanyId(String companyId) {
        List<CompanyEmployee> companyEmployeeList = this.lambdaQuery().eq(CompanyEmployee::getCompanyId, companyId).list();
        return companyEmployeeList;
    }

    /**
     * 获取公司所有用户(分页)
     *
     * @param page     分页
     * @param searchVo 搜索对象
     */
    public List<UserMapstruct.UserAndCompanySimpleVo> getCompanyAllUserPage(
            RequestPage page,
            CompanyEmployeeMapstruct.PageSearchVo searchVo
    ) {
        List<CompanyEmployee> companyEmployeeList = this.getBaseMapper().getCompanyAllUserPage(page, searchVo);
        List<UserMapstruct.UserAndCompanySimpleVo> userAndCompanySimpleVoList = this.assembleUserAndCompanySimpleVoList(companyEmployeeList);
        page.setRecords(userAndCompanySimpleVoList);
        return userAndCompanySimpleVoList;
    }

    /**
     * 组装UserAndCompanySimpleVo
     *
     * @param companyEmployeeList 员工数据
     */
    private List<UserMapstruct.UserAndCompanySimpleVo> assembleUserAndCompanySimpleVoList(
            List<CompanyEmployee> companyEmployeeList
    ) {

        List<UserMapstruct.UserAndCompanySimpleVo> userVoList = new ArrayList<>(0);
        if (ListUtils.isNotExistsEle(companyEmployeeList)) {
            return userVoList;
        }

        //用户ID去重
        List<String> userIdList = companyEmployeeList.stream().map(CompanyEmployee::getUserId).distinct().collect(Collectors.toList());
        if (ListUtils.isNotExistsEle(userIdList)) {
            return userVoList;
        }

        String companyId = companyEmployeeList.get(0).getCompanyId();
        //获取用户公司
        Company company = baseCompanyService.getById(companyId);
        //获取部门
        List<CompanyDepartment> companyAllCompanyDepartment = baseCompanyDepartmentService.getByCompanyId(companyId);
        Map<String, CompanyDepartment> companyDepartmentMap = new HashMap<>(0);
        if (ListUtils.isExistsEle(companyAllCompanyDepartment)) {
            companyDepartmentMap = companyAllCompanyDepartment.stream().collect(Collectors.toMap(d -> d.getCompanyDepartmentId(), d -> d));
        }

        List<CompanyDepartmentEmployee> userAllDepartmentList = baseCompanyDepartmentEmployeeService.getByCompanyId(companyId, null);

        //获取公司所有角色
        List<PermissionRole> companyPermissionRoleList = basePermissionRoleService.lambdaQuery().eq(PermissionRole::getCompanyId, companyId).list();

        //查询用户信息
        List<User> userList = baseUserService.lambdaQuery()
                .in(User::getUserId, userIdList)
                .list();
        if (ListUtils.isNotExistsEle(userList)) {
            return userVoList;
        }

        //转换简单对象
        userVoList = UserMapstruct.INSTANCE.toUserAndCompanySimpleVoList(userList);
        Map<String, CompanyDepartment> finalCompanyDepartmentMap = companyDepartmentMap;
        userVoList.forEach(userVo -> {

            userVo.setCompanyId(company.getCompanyId());
            userVo.setCompanyName(company.getCompanyName());
            userVo.setCompanyLevel(company.getCompanyLevel());

            if (ListUtils.isExistsEle(userAllDepartmentList)) {
                userAllDepartmentList.stream().filter(d -> d.getUserId().equals(userVo.getUserId()) && !d.getIsPartTimeJob()).findFirst().ifPresent(d -> {
                    CompanyDepartment companyDepartment = finalCompanyDepartmentMap.get(d.getCompanyDepartmentId());
                    if (companyDepartment != null) {
                        userVo.setCompanyDepartmentId(companyDepartment.getCompanyDepartmentId());
                        userVo.setCompanyDepartmentName(companyDepartment.getCompanyDepartmentName());
                        userVo.setEmployeeId(d.getCompanyEmployeeId());
                        userVo.setJobName(d.getJobName());
                        userVo.setIsDepartmentPrincipal(d.getIsPrincipal());
                    }
                });
            }

            //填充用户角色
            List<PermissionRoleMapstruct.PermissionRoleIdAndNameVo> processRoleList = new ArrayList<>();
            userVo.setProcessRoleList(processRoleList);
            List<String> roleIdList = basePermissionMapRoleUserService.getRoleIdByUserIdAndCompanyId(userVo.getUserId(), company.getCompanyId());
            if (ListUtils.isExistsEle(companyPermissionRoleList)) {
                List<PermissionRole> userRoleList = companyPermissionRoleList.stream().filter(d -> roleIdList.contains(d.getPermissionRoleId())).collect(Collectors.toList());
                for (PermissionRole permissionRole : userRoleList) {
                    PermissionRoleMapstruct.PermissionRoleIdAndNameVo permissionRoleIdAndNameVo = new PermissionRoleMapstruct.PermissionRoleIdAndNameVo();
                    processRoleList.add(permissionRoleIdAndNameVo);

                    permissionRoleIdAndNameVo.setPermissionRoleId(permissionRole.getPermissionRoleId());
                    permissionRoleIdAndNameVo.setPermissionRoleName(permissionRole.getRoleName());
                }
            }
        });
        return userVoList;
    }

    @Transactional(rollbackFor = Exception.class)
    public void delByCompanyId(String companyId) {
        this.lambdaUpdate().eq(CompanyEmployee::getCompanyId,companyId).remove();
    }
}
